package br.org.espmessenger.cliente;

import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.rmi.Naming;

import br.org.espmessenger.middleware.ESPMessenger;
import br.org.espmessenger.middleware.InfraEstruturaException;
import br.org.espmessenger.modelo.Usuario;
import br.org.espmessenger.modelo.excecoes.UsuarioJaCadastradoException;

/**
 * Classe utilitária que implementa o padrão
 * ServiceLocator (Core J2EE Patterns)
 * 
 */
public class AgenteDeInfraEstrutura {
	private static AgenteDeInfraEstrutura instance;
	private ESPMessenger messenger;
	
	public static AgenteDeInfraEstrutura getInstance() throws InfraEstruturaException {
		if (instance == null) {
			instance = new AgenteDeInfraEstrutura();
		}
		return instance;
	}

	private AgenteDeInfraEstrutura() throws InfraEstruturaException {
		Servidor servidor = new Servidor();
		servidor.setHost(Fachada.getInstance().getEntrada("servidor.host")+"");
		servidor.setPorta(Integer.parseInt(Fachada.getInstance().getEntrada("servidor.porta")+""));
		servidor.setServico(Fachada.getInstance().getEntrada("servidor.servico")+"");
		messenger = conectarRMI(servidor);
	}
	

	public ESPMessenger getMessenger() {
		return messenger;
	}
	
	public static void testarServidor(Servidor servidor) throws InfraEstruturaException {
		// Teste de host
		InetAddress host = null;
		try {
			host = InetAddress.getByName(servidor.getHost());
			if (!host.isReachable(3000)) {
				throw new InfraEstruturaException("Host inacessível!");
			}
			
		} catch (IOException e) {
			throw new InfraEstruturaException("Host inacessível!", e);
		}
		
		// Teste de porta
		try {
			Socket sock = new Socket(host, servidor.getPorta());
			sock.close();
		} catch (IOException e) {
			throw new InfraEstruturaException("Conexão negada pelo servidor remoto!", e);
		}
		
		conectarRMI(servidor);
	}

	private static ESPMessenger conectarRMI(Servidor servidor)
			throws InfraEstruturaException {
		// Teste de serviço RMI
		try {
			return (ESPMessenger) Naming.lookup(
									String.format("rmi://%s:%d/%s",
									servidor.getHost(),
									servidor.getPorta(),
									servidor.getServico()));
		} catch (Exception e) {
			throw new InfraEstruturaException("Serviço indisponível!", e);
		}
	}
}
